/******************************************
 * Nombre del archivo: At_Lista.java
 * Universidad del Valle de Guatemala
 * Curso: Algoritmos y Estructura de Datos
 * Autores:
 *      * Martín Guzmán     08041
 *      * David Hsieh       08225
 *      * Eduardo Mejicano  08058
 *      * Kevin Sánchez     08302
 * Fecha: 16 de agosto de 2009
 * Descripción:
*******************************************/
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.Scanner;

public class At_Lista extends Atomo{

    LinkedList<Atomo> lista = new LinkedList<Atomo>();
    At_Lista sub_lista;
    String texto_lista="";
    private static Scanner scan = new Scanner(System.in);

    public At_Lista(String lista){
        texto_lista=lista;
        //System.out.println("DENTRO DE LISTA LITERAL"+texto_lista);//TODO quitar esto
        Arreglar_texto();
        //System.out.println("DENTRO DE LISTA LITERAL2"+texto_lista);//TODO quitar esto
    }
    
    
    /*****************************************
     * Método: Arreglar_texto
     * Autor: Martín Guzmán
     * Uso: divide en átomos el texto
     * Retorno: guarda los átomos en una lista.
     *****************************************/
    public void Arreglar_texto(){
        String[] temporal=texto_lista.split(",");
        
        //pasar a una lista el arreglo de strings
        ArrayList<String> temporal_lista = new ArrayList<String>();
        for(int i=0;i<temporal.length;i++)
        {
            temporal_lista.add(temporal[i]);
        }
        //***********************************
        ArrayList<String> temporal_a_agregar = new ArrayList<String>();
        for(int i=0;i<temporal_lista.size();i++)
        {
            String sub_cadena=temporal_lista.get(i);
            if (temporal_lista.get(i).startsWith("("))//agrupar hasta que se cierre este paréntesis
            {
                int parentesis=1;
                int posicion=i;
                for(int j=i+1;j<temporal_lista.size();j++){
                    if(temporal[j].contains(")"))
                        parentesis--;
                    if (parentesis==0){
                        posicion=j;
                        break;
                    }
                    if(temporal[j].startsWith("("))
                        parentesis++;

                }
                sub_cadena="";
                //System.out.println("i"+i+" j:"+posicion);//TODO quitar esto
                for(int a=i;a<=posicion;a++){
                   sub_cadena+=","+temporal_lista.get(a);
                }
                sub_cadena=sub_cadena.substring(1, sub_cadena.length());//para quitarle la última ","
                i=posicion;
            }
            //System.out.println("Sub-cadena: ."+sub_cadena+".");//TODO quitar esto
            temporal_a_agregar.add(sub_cadena);
        }
        Agregar_a_lista(temporal_a_agregar);
    }

    /*****************************************
     * Método: Agregar_a_lista
     * Autor: Martín Guzmán
     * Uso: agrega a la lista un átomo,
     *      clasificándolos. Lista contiene
     *      todos los átomos.
     * Retorno: guarda los átomos en una lista.
     *****************************************/
    public void Agregar_a_lista(ArrayList<String> listado){
        
        if(listado.get(0).compareToIgnoreCase("COND")==0){

            String texto2="";
            for(int a=1;a<listado.size();a++){
                texto2+=listado.get(a)+",";
            }
            //para quitarle la última coma:
            texto2= (texto2.substring(0,texto2.length()-1));
            //***********************************************************

            //System.out.println("texto2 en el cond: "+texto2);//TODO quitar esto//DEbugear

            Cond nueva_condicion = new Cond("(,COND,"+texto2+",)");

            String temporal2=nueva_condicion.Obtener_valor();
            if(temporal2.compareToIgnoreCase("")!=0){

                //System.out.println("Salió bien la condición!!");//TODO quitar esto//DEbuguear
                this.lista.add(new At_Variable(temporal2));
            }
            else{
                System.out.println("An error has ocurred with the condition COND");
                this.lista.clear(); //borra la lista debido a que no está completa
            }
        }
        else if(listado.get(0).startsWith("DEFUN")){
            try{
            //System.out.println("función dentro de una lista");
                System.out.println("bla"+ ".("+texto_lista+").");

                Funcion nueva_funcion= new Funcion("(,"+texto_lista+",)");
            }catch(Exception exp){
                System.out.println("Funtion sintaxis incorrect");
            }
        }
        else if(listado.get(0).startsWith("MAPCAR")){
            try{
            //System.out.println("función dentro de una lista");
                String temp="";
                for(int i=0;i<listado.size();i++){
                    temp+=","+listado.get(i);
                }
                Mapcar nuevo = new Mapcar(temp);
                String result_mapcar = nuevo.getResult();
                if(result_mapcar.isEmpty()!=true){
                    this.lista.add(new At_Variable(result_mapcar));
                }
                else
                {
                    System.out.println("A problem has ocurred in the MAPCAR sintaxis");
                    this.lista.clear();
                }

            }catch(Exception exp){
                System.out.println("MAPCAR sintaxis incorrect");
            }
        }
        //es la evaluación de una función (llamada a la función)
        else if(Funcion.Buscar(listado.get(0))==true){
            //System.out.println("Llamada a una función");//TODO quitar esto //debuguear
            String texto2="";
            for(int a=1;a<listado.size();a++){
                texto2+=listado.get(a)+",";
            }
            //***********************************************************
            //System.out.println("texto2: "+(texto2.substring(0,texto2.length()-1)));//TODO quitar esto//DEbugear
            int indice=Funcion.Buscar_Indice(listado.get(0));
            //String temporal2=Funcion.getFunciones().get(indice).replace(new At_Lista_Literal(texto2.substring(0,texto2.length()-1)));
            String temporal2=Funcion.getFunciones().get(indice).replace(texto2.substring(0,texto2.length()-1));
            if(temporal2.compareToIgnoreCase("")!=0){
                try{//System.out.println("SÍ REEMPLAZÓ!!");//TODO quitar esto//DEbuguear
                    String resultado_op = Funcion.getFunciones().get(indice).Obtener_valor(temporal2);
                    this.lista.add(new At_Variable(resultado_op));
                }
                catch(Exception exp){
                    System.out.println("Operands do not match in the funtion "+listado.get(0));
                }
            }
            else{
                //System.out.println("NO REEMPLAZÓ!!");//TODO quitar esto//DEbuguear
                System.out.println("An error has ocurred when calling the funtion "+listado.get(0));
                this.lista.clear(); //borra la lista debido a que no está completa
            }
        }
        else if (listado.get(0).compareToIgnoreCase("SETQ")==0) {
            ///System.out.println("SETQ!!"); //TODO REMOVE
            At_Lista_Literal temporal1;
            try
            {
                if (listado.get(2).compareToIgnoreCase("'")==0){

                    temporal1= new At_Lista_Literal(listado.get(3));
                    //System.out.println(listado.get(3));
                    String temp = temporal1.Obtener_valor();
                    //System.out.println(temp);
                    Lista_Variables.setq(listado.get(1), temp);
                    this.lista.add(new At_Variable(temp));
                }
                else {
                    for(int i=0;i<listado.size();i++){
                        //System.out.println("listado: "+listado.get(i));
                        if(listado.get(i).startsWith("(")){//Revisar si es una lista
                            //System.out.println("Nueva lista");//TODO quitar esto //debuguear
                            this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                            sub_lista= (At_Lista)lista.get(i);
                            if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                                this.lista.clear(); //borra la lista debido a que no está completa
                            }
                        }else{
                            if(Lista_Variables.getValor(listado.get(i))==null)
                                this.lista.add(new At_Variable((listado.get(i))));
                            else{
                                //System.out.println(listado.get(i));
                                this.lista.add(new At_Variable(listado.get(i),true));
                            }
                            //System.out.println(listado.get(i));
                        }

                    }
                }
            }catch(Exception ex){
                System.out.println("Sorry, SETQ sintaxis is not correct.");
                this.lista.clear(); //borra la lista debido a que no está completa
            }
            if(this.lista.size()<1){//Faltan operandos
                System.out.println("Missing operands in the SETQ.");
                this.lista.clear(); //borra la lista debido a que no está completa
            }
        }
        //Revisar si el operando es aritmético o bien un CAR con una lista literal detrás
        else if (Op_Aritmetica.Buscar(listado.get(0))){
            //agrega un operador
            this.lista.add(new At_Operador(listado.get(0)));
            for(int i=1;i<listado.size();i++){

                //System.out.print(listado.get(i)+"  ");//TODO quitar esto//debuguear

                if(listado.get(i).startsWith("(")){//Revisar si es una lista
                    //System.out.println("Nueva lista");//TODO quitar esto //debuguear

                    this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                    sub_lista= (At_Lista)lista.get(i);
                    if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                        this.lista.clear(); //borra la lista debido a que no está completa
                    }
                }else{
                    //System.out.println("Nueva variable o constante");//TODO quitar esto //debuguear
                    this.lista.add(new At_Variable((listado.get(i))));
                }

            }
            if(this.lista.size()<3){//Faltan operandos
                System.out.println("Sorry, missing operands.");
                this.lista.clear(); //borra la lista debido a que no está completa
            }
        }
        else if (Op_Predicados2.Buscar(listado.get(0)) && !listado.get(1).startsWith("'")){
            //agrega un operador
            this.lista.add(new At_Operador(listado.get(0)));
            for(int i=1;i<listado.size();i++){

                if(listado.get(i).startsWith("(")){//Revisar si es una lista
                    //System.out.println("Nueva lista");//TODO quitar esto //debuguear

                    this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                    sub_lista= (At_Lista)lista.get(i);
                    if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                        this.lista.clear(); //borra la lista debido a que no está completa
                    }
                }else{
                    //System.out.println("Nueva variable o constante");//TODO quitar esto //debuguear
                    this.lista.add(new At_Variable((listado.get(i))));
                }

            }
            if(this.lista.size()<3){//Faltan operandos
                if(lista.size()>0 && this.lista.get(0).toString().compareToIgnoreCase("ATOM") != 0) {
                    System.out.println("Sorry, missing operands.");
                    this.lista.clear(); //borra la lista debido a que no está completa
                }
            }
        }
        else if (Op_Predicados.Buscar(listado.get(0)) && !listado.get(1).startsWith("'")){
            //agrega un operador
            this.lista.add(new At_Operador(listado.get(0)));
            for(int i=1;i<listado.size();i++){

                if(listado.get(i).startsWith("(")){//Revisar si es una lista
                    //System.out.println("Nueva lista");//TODO quitar esto //debuguear

                    this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                    sub_lista= (At_Lista)lista.get(i);
                    if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                        this.lista.clear(); //borra la lista debido a que no está completa
                    }
                }else{
                    //System.out.println("Nueva variable o constante");//TODO quitar esto //debuguear
                    this.lista.add(new At_Variable((listado.get(i))));
                }

            }
            if(this.lista.size()<2){//Faltan operandos

                    System.out.println("Sorry, missing operands.");
                    this.lista.clear(); //borra la lista debido a que no está completa

            }
        }
        else if (Op_Entrada.Buscar(listado.get(0))){
            //agrega un operador
            this.lista.add(new At_Operador(listado.get(0)));
            for(int i=1;i<listado.size();i++){

                if(listado.get(i).startsWith("(")){//Revisar si es una lista
                    //System.out.println("Nueva lista");//TODO quitar esto //debuguear

                    this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                    sub_lista= (At_Lista)lista.get(i);
                    if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                        this.lista.clear(); //borra la lista debido a que no está completa
                    }
                }else{
                    //System.out.println("Nueva variable o constante");//TODO quitar esto //debuguear
                    this.lista.add(new At_Variable((listado.get(i))));
                }

            }
            if(this.lista.size()<1){//Faltan operandos

                    System.out.println("Sorry, missing operands.");
                    this.lista.clear(); //borra la lista debido a que no está completa

            }
        }
        else if (Op_Iterador.Buscar(listado.get(0))){
            //agrega un operador
            this.lista.add(new At_Operador(listado.get(0)));
            for(int i=1;i<listado.size();i++){

                if(listado.get(i).startsWith("(")){//Revisar si es una lista
                    //System.out.println("Nueva lista");//TODO quitar esto //debuguear

                    this.lista.add(new At_Lista(listado.get(i).substring(2,listado.get(i).length()-2)));//nueva lista y corta el (, y el ,)
                    sub_lista= (At_Lista)lista.get(i);
                    if (sub_lista.lista.size()==0){//Significa que hay algo mal adentro de la lista
                        this.lista.clear(); //borra la lista debido a que no está completa
                    }
                }else{
                    //System.out.println("Nueva variable o constante");//TODO quitar esto //debuguear
                    this.lista.add(new At_Variable((listado.get(i))));
                }

            }
            if(this.lista.size()<3){//Faltan operandos
                System.out.println("Sorry, missing operands.");
                this.lista.clear(); //borra la lista debido a que no está completa
            }
        }
        else if( listado.get(0).compareToIgnoreCase("CAR")==0) {
            /*2 caminos:
             *      (CAR '(1 2 3)): LISTA LITERAL DESPUÉS DEL CAR
             *      (CAR (CDR '(1 2 3))): LISTA NORMAL CON UN CDR QUE DEVUELVE UNA LISTA LITERAL
            */
            At_Lista_Literal temporal1;
            //System.out.println("Nuevo operando CAR "+listado.get(1));//TODO quitar esto //debuguear

            //revisa el primer camino
            if (listado.get(1).compareToIgnoreCase("'")==0){

                //System.out.println("CAR CON '(...");//TODO quitar esto //debuguear
                //System.out.println("a convertir: "+listado.get(2));//TODO quitar esto
                temporal1= new At_Lista_Literal(listado.get(2));
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if(Lista_Variables.getValor(listado.get(1)) != null) {
                //System.out.println("SI SE METIO HASTA ACA");
                String temp = Main.Quitar_espacios(Lista_Variables.getValor(listado.get(1)));
                temporal1 = new At_Lista_Literal(temp);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }

            //el segundo camino
            else if (listado.get(1).startsWith("(,CDR")){
                //System.out.println("CAR CON (CDR...");//TODO quitar esto //debuguear
                temporal1= new At_Lista_Literal(listado.get(1),true);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }

            }
            else if (listado.get(1).startsWith("(,CAR")){
                //System.out.println("CAR CON (CAR...");//TODO quitar esto //debuguear
                temporal1= new At_Lista_Literal(listado.get(1),true);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).startsWith("(,LIST")){
                //System.out.println("CAR CON (LIST...");//TODO quitar esto //debuguear
                At_Lista temp2 = new At_Lista(listado.get(1).substring(2,listado.get(1).length()-2));
                //System.out.println("Valor obtenido de la lista "+temp2.Obtener_valor());
                temporal1= new At_Lista_Literal(temp2.Obtener_valor());
                //System.out.println("tamaño de la lista creada con list "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).startsWith("(,MAPCAR")){
                //System.out.println("CAR CON (MAPCAR...");//TODO quitar esto //debuguear
                At_Lista temp2 = new At_Lista(listado.get(1).substring(2,listado.get(1).length()-2));
                //System.out.println("Valor obtenido de la lista "+temp2.Obtener_valor());
                temporal1= new At_Lista_Literal(temp2.Obtener_valor());
                //System.out.println("tamaño de la lista creada con list "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).compareToIgnoreCase("(,READ,)")==0){
                //System.out.println("CAR CON (READ...");//TODO quitar esto //debuguear
                String A = scan.nextLine();
                //scan.next();
                temporal1= new At_Lista_Literal(A);
                //System.out.println("tamaño de la lista creada con read "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
        }
        else if( listado.get(0).compareToIgnoreCase("CDR")==0) {
            /*2 caminos:
             *      (CDR '(1 2 3)): LISTA LITERAL DESPUÉS DEL CAR
             *      (CDR (CDR '(1 2 3))): LISTA NORMAL CON UN CDR QUE DEVUELVE UNA LISTA LITERAL
            */
            At_Lista_Literal temporal1;

            //System.out.println("Nuevo operando CDR");//TODO quitar esto //debuguear
            //revisa el primer camino
            if (listado.get(1).compareToIgnoreCase("'")==0){

                //System.out.println("CDR CON '(...");//TODO quitar esto //debuguear
                //System.out.println("a convertir: "+listado.get(2));//TODO quitar esto
                temporal1= new At_Lista_Literal(listado.get(2));
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if(Lista_Variables.getValor(listado.get(1))!=null) {
                //System.out.println("SI SE METIO HASTA ACA");
                String temp = Main.Quitar_espacios(Lista_Variables.getValor(listado.get(1)));
                temporal1= new At_Lista_Literal(temp);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            //el segundo camino
            else if (listado.get(1).startsWith("(,CDR")){
                //System.out.println("CDR CON (CDR...");//TODO quitar esto //debuguear
                temporal1= new At_Lista_Literal(listado.get(1),true);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
                
                //System.out.println("a: "+lista.getLast().Obtener_valor());//TODO quitar esto
            }
            else if (listado.get(1).startsWith("(,CAR")){
                //System.out.println("CDR CON (CAR...");//TODO quitar esto //debuguear
                temporal1= new At_Lista_Literal(listado.get(1),true);
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).startsWith("(,LIST")){
                //System.out.println("CDR CON (LIST...");//TODO quitar esto //debuguear
                At_Lista temp2 = new At_Lista(listado.get(1).substring(2,listado.get(1).length()-2));
                //System.out.println("Valor obtenido de la lista "+temp2.Obtener_valor());
                temporal1= new At_Lista_Literal(temp2.Obtener_valor());
                //System.out.println("tamaño de la lista creada con list "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).startsWith("(,MAPCAR")){
                //System.out.println("CDR CON (MAPCAR...");//TODO quitar esto //debuguear
                At_Lista temp2 = new At_Lista(listado.get(1).substring(2,listado.get(1).length()-2));
                //System.out.println("Valor obtenido de la lista "+temp2.Obtener_valor());
                temporal1= new At_Lista_Literal(temp2.Obtener_valor());
                //System.out.println("tamaño de la lista creada con list "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
            else if (listado.get(1).compareToIgnoreCase("(,READ,)")==0){
                //System.out.println("CDR CON (READ...");//TODO quitar esto //debuguear
                String A = scan.nextLine();
                //scan.next();
                temporal1= new At_Lista_Literal(A);
                //System.out.println("tamaño de la lista creada con read "+temporal1.getList().size());
                String temporal_resultado=Op_Listas.Operar(listado.get(0), temporal1);
                //System.out.println("temporal_resultado:."+temporal_resultado+".");

                if(temporal_resultado.isEmpty()){
                    this.lista.clear(); //borra la lista debido a que hay un error
                }
                else{
                    this.lista.add(new At_Variable((temporal_resultado)));
                }
            }
        }
        else if (Op_Listas.Buscar(listado.get(0))){
            if(listado.get(0).compareToIgnoreCase("LIST")==0){
                LinkedList<String> temp1 = new LinkedList<String>();
                //copiar la lista de las cosas que van a ser agregadas con LIST
                for(int i=1;i<listado.size();i++){
                    temp1.add(listado.get(i));
                }
                String temporal_resultado = Op_Listas.Operar_List("LIST", temp1);
                this.lista.add(new At_Variable(temporal_resultado));
            }
            else{
                //sería un "'"
                System.out.println("Invalid expression. You can not have a literal list inside a list.");//TODO ver otra forma de manejar
                this.lista.clear(); //borra la lista debido a que no está completa
            }
            
        }
        else if (listado.get(0).compareToIgnoreCase("ATOM")==0) {
            System.out.println("!!"); //TODO REMOVE
            
            if (listado.get(1).compareToIgnoreCase("'")==0){
                
                while(listado.size()>3) 
                    listado.remove(listado.size()-1);
                System.out.println( Op_Predicados2.Operar(listado.get(0), listado.get(1)));
                
            }
        }
        //no se pudo agregar operando, por lo tanto está mala la sintaxis
        else{
            //no tiene operador
            System.out.println("Sorry, you have no operator.");//TODO ver otra forma de manejar
            this.lista.clear(); //borra la lista debido a que no está completa
        }

    }

    /*****************************************
     * Método: Obtener_valor
     * Autor: Martín Guzmán
     * Uso: Obtiene el valor de una expresión
     * Retorno: valor de la evaluación de la
     *          lista.
     *****************************************/
    public String Obtener_valor(){
        /*
        for(int i=0;i<lista.size();i++){
            System.out.println(lista.get(i).Obtener_valor());
        }
         */
        
        if(Op_Aritmetica.Buscar(lista.get(0).Obtener_valor())){
            try{
                int result=Integer.parseInt(lista.get(1).Obtener_valor());//primer operando
                for(int i=2;i<this.lista.size();i++){
                    //System.out.println("."+lista.get(i).Obtener_valor()+".");//TODO quitar esto //debuguear
                    //lista.get(0).toString() es la operación
                    result=Integer.parseInt(Op_Aritmetica.Operar(lista.get(0).Obtener_valor(),result,Integer.parseInt(lista.get(i).Obtener_valor())));
                }
                return ""+result;
            }catch(Exception exp){
                return ("Error. You are trying to operate something that is not a number\nA problem has ocurred. Your operation is not correct.");
            }
        }
        else if(Op_Predicados2.Buscar(lista.get(0).Obtener_valor())){
            try{
                String result=lista.get(1).Obtener_valor();//primer operando
                //System.out.println(lista.get(0).Obtener_valor());

                if(lista.get(0).Obtener_valor().compareToIgnoreCase("ATOM")==0) {
                    result=Op_Predicados2.Operar(lista.get(0).Obtener_valor(),lista.get(1).Obtener_valor());

                }
                else

                for(int i=2;i<this.lista.size();i++){
                    //System.out.println("."+lista.get(i).Obtener_valor()+".");//TODO quitar esto //debuguear
                    //lista.get(0).toString() es la operación
                    result=Op_Predicados2.Operar(lista.get(0).Obtener_valor(),result,lista.get(i).Obtener_valor());
                }
                return ""+result;
            }catch(Exception exp){
                return ("Error. You are trying to operate something that is not a number\nA problem has ocurred. Your operation is not correct.");
            }
        }
        else if(Op_Predicados.Buscar(lista.get(0).Obtener_valor())){
            try{
                String result=lista.get(1).Obtener_valor();//primer operando
                //System.out.println(lista.get(0).Obtener_valor());

                for(int i=1;i<this.lista.size();i++){
                    //System.out.println("."+lista.get(i).Obtener_valor()+".");//TODO quitar esto //debuguear
                    //lista.get(0).toString() es la operación
                    result=Op_Predicados.Operar(lista.get(0).Obtener_valor(),result);
                }
                return ""+result;
            }catch(Exception exp){
                return ("Error. You are trying to operate something that is not a number\nA problem has ocurred. Your operation is not correct.");
            }
        }
        else if(Op_Entrada.Buscar(lista.get(0).Obtener_valor())){
            try{
                    String result=Op_Entrada.Operar(lista.get(0).Obtener_valor());


                return ""+result;
            }catch(Exception exp){
                return ("Error. You are trying to operate something that is not a number\nA problem has ocurred. Your operation is not correct.");
            }
        }
        ///*************************************************************************************************************************************************
        ///*************************************************************************************************************************************************
        else if(Op_Iterador.Buscar(lista.get(0).Obtener_valor()))
        {
            try{
                int result=Integer.parseInt(lista.get(1).Obtener_valor());//primer operando
                for(int i=2;i<this.lista.size();i++){
                    //System.out.println("."+lista.get(i).Obtener_valor()+".");//TODO quitar esto //debuguear
                    //lista.get(0).toString() es la operación
                    result=Integer.parseInt(Op_Iterador.Operar(lista.get(0).Obtener_valor(),result,Integer.parseInt(lista.get(i).Obtener_valor())));
                }
                return ""+result;
            }catch(Exception exp){
                return ("Error. You are trying to operate something that is not a number\nA problem has ocurred. Your operation is not correct.");
            }
        }
        ///*************************************************************************************************************************************************
        ///*************************************************************************************************************************************************
        else if(lista.get(0).Obtener_valor().compareToIgnoreCase("SETQ")==0) {
            //System.out.println("SI ES SETQ"); //REMOVE
            String result = Lista_Variables.setq(lista.get(1).Obtener_valor(), lista.get(2).Obtener_valor());
            return result;
        }
        else
        {
            //debería de ser una Variable
            return lista.get(0).Obtener_valor();
        }
    }

}
